﻿using System.Collections.Generic;
using System;
using BasicParts;

namespace MessageMachine
{
    public class MessagePasser
    {
        private static Dictionary<int, List<IGenSubscriber>> subs
            = new Dictionary<int, List<IGenSubscriber>>();

        public static void Send<T>(int type)
        {
            if (subs.ContainsKey(type))
                subs[type].ForEach(s => s.Receive<T>(type));
        }


        private static Dictionary<int, List<Tuple<ISubscriber, bool>>> subscribers
            = new Dictionary<int, List<Tuple<ISubscriber, bool>>>();

        public static void Send(Message msg)
        {
            if (subscribers.ContainsKey(msg.msgType))
                if (msg.receivers == null)
                    subscribers[msg.msgType].ForEach(s => s.Item1.Receive(msg));
                else
                    subscribers[msg.msgType].FindAll(s => s.Item2 || msg.receivers.Contains(s.Item1))
                        .ForEach(s => s.Item1.Receive(msg));
        }

        public static bool Subscribe(int msgType, ISubscriber self, bool priority = false)
        {
            if (!subscribers.ContainsKey(msgType))
                subscribers.Add(msgType, new List<Tuple<ISubscriber, bool>>());
            if (subscribers[msgType].Contains(
                new Tuple<ISubscriber, bool>(self, priority))) return false;
            subscribers[msgType].Add(new Tuple<ISubscriber, bool>(self, priority));
            return true;
        }
        public static void Subscribe(int[] msgTypes, ISubscriber self, bool priority = false)
        {
            for (int k = 0; k < msgTypes.Length; k++)
                Subscribe(msgTypes[k], self, priority);
        }

        /// <summary>
        /// Unsubscribes an object from a given extraInfo msg.
        /// </summary>
        /// <param name="msgType">The undesired extraInfo msg.</param>
        /// <param name="self">The object doing the unsubscription.</param>
        /// <returns>True if successful, otherwise false.</returns>
        public static bool Unsubscribe(int msgType, ISubscriber self)
        {
            if (subscribers.ContainsKey(msgType))
                subscribers[msgType].RemoveAll(s => s.Item1.Equals(self));
            else return false;
            return true;
        }

        public static void Unsubscribe(int[] msgTypes, ISubscriber self)
        {
            for (int k = 0; k < msgTypes.Length; k++)
                Unsubscribe(msgTypes[k], self);
        }
    }
}
